<?php
/**
 * 
 * @author Ardy Dedase
 *
 */
interface ISearch
{
	function onSearch($engine, $args);
}

class SearchAPI 
{
	public static $_query;
	public static $_apikey;
	public static $_version;
	public static $_userip;	
	public static $_numresults = 'small';
	public static $_start = 1;
	public static $_callback;
	public static $_context;
	
	// search result variable
	public static $_result;			
	
	private $_searches = array();
	
	public function addSearch( $search )
	{
		$this->_searches[] = $search;
	}

	public function runSearch( $engine )
	{
		$args = array();	
		foreach( $this->_searches as $search )
		{
			$result = $search->onSearch( $engine, $args );
			if ( $result )
				return $result;
		}
	}
	
	public function getArgs()
	{
		return $this->_query;
	}
		
}

class GoogleAPI extends SearchAPI
{		
	const WEB = 'http://ajax.googleapis.com/ajax/services/search/web';
	const LOCAL = 'http://ajax.googleapis.com/ajax/services/search/local';
	const VIDEO = 'http://ajax.googleapis.com/ajax/services/search/video';
	const BLOG = 'http://ajax.googleapis.com/ajax/services/search/blogs';
	const NEWS = 'http://ajax.googleapis.com/ajax/services/search/news';
	const BOOK = 'http://ajax.googleapis.com/ajax/services/search/books';
	const IMAGE = 'http://ajax.googleapis.com/ajax/services/search/images';
	const PATENT = 'http://ajax.googleapis.com/ajax/services/search/patent';
	
	public $_baseURI;
	
	
	public function __construct($searchType)
	{
		echo $this->_query;
		switch($searchType)
		{
			case 'web':
				$this->_baseURI = self::WEB;
				break;
			case 'local':
				$this->_baseURI = self::LOCAL;				
				break;
			case 'video':
				$this->_baseURI = self::VIDEO;				
				break;				
			default:
				$this->_baseURI = self::WEB;
				break;
		}	
	}
}

class YahooSearch
{
	
}

/**
 * SearchOperation
 * This class will handle most of the logic
 */
class SearchOperation
{
	private $_searchType;
	
	public function  __construct($searchType)
	{
		$this->_searchType = $searchType;		
	}
	
	private function sendRequest($query)
	{
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $query);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($ch, CURLOPT_REFERER, '');
		$body = curl_exec($ch);
		curl_close($ch);
		
		// now, process the JSON string
		$res = json_decode($body);
//		echo '<pre>' , print_r($res, true) , '</pre>';
		return $res;
	}	
	
	private function getGoogleQueryStr()
	{
		$api = new GoogleAPI($this->_searchType);
		
		//google's API doesn't accept any number greater than 8, so we'll used their pre-defined value instead
		SearchAPI::$_numresults = (SearchAPI::$_numresults >= 8) ? 'filtered_cse' : SearchAPI::$_numresults;
		
		$args = array(			
			'rsz' => SearchAPI::$_numresults,
			'key' => SearchAPI::$_apikey,
			'start' => SearchAPI::$_start,
			'callback' => SearchAPI::$_callback,
			'context' => SearchAPI::$_context,
			'userip' => SearchAPI::$_userip						 
		);
		
		$args = array_filter($args);
		
		return $api->_baseURI . '?v=1.0&q=' . rawurlencode(SearchAPI::$_query) . '&' . http_build_query($args);
		
	}	

	public function googleSearch()
	{
		$query = $this->getGoogleQueryStr();
		$result = $this->sendRequest($query);
		
		return $result;
	}	
}

class Search implements ISearch
{
	private $_searchType;
	
	public function __construct($searcyType)
	{
		$this->_searchType = $searcyType;
	}
	
	public function onSearch($engine, $args)
	{
		$operation = new SearchOperation($this->_searchType);
		
		switch($engine)
		{
			case 'google':
				$result = $operation->googleSearch();
				break;		
		}
		
		return $result;
	}	
}

/* to test, uncomment this block
$searchAPI = new SearchAPI();

$searchAPI->addSearch( new Search('web') );

$searchAPI::$_query = 'open source';

$searchAPI::$_apikey = 'Your-API-Key';
$searchAPI::$_numresults = '8';
$searchAPI::$_start = 11;

$result = $searchAPI->runSearch( 'google' );

echo '<pre>', print_r($result, true) , '</pre>';
*/
?>